<!DOCTYPE html>
<html lang="en" dir="ltr">
    <head><meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'><meta name='description' content="用户态与内核态\rJDK早期，synchronized 叫做重量级锁， 因为申请锁资源必须通过kernel, 系统调用 ;hello.asm\r;write(int fd, const void *buffer, size_t nbytes)\rsection data\rmsg db \"Hello\", 0xA\rlen equ $ - msg\rsection .text\rglobal _start\r_start:\rmov edx, len\rmov ecx, msg\rmov ebx, 1 ;文件描述符1 std_out\rmov eax, 4 ;write函数系统调用号 4\rint 0x80\rmov ebx, 0\rmov eax, 1 ;exit函数系统调用号\rint 0x80\rCAS\rCompare And Swap (Compare And Exchange) / 自旋 / 自旋锁 / 无锁 （无重量锁）">
<title>多线程高并发</title>

<link rel='canonical' href='http://laoxia.cc/p/%E5%A4%9A%E7%BA%BF%E7%A8%8B%E9%AB%98%E5%B9%B6%E5%8F%91/'>

<link rel="stylesheet" href="/scss/style.min.8e60baf4cd3fc55968717a6e39762f4d28ed7ef6007566b6c7970ad0fe907198.css"><meta property='og:title' content="多线程高并发">
<meta property='og:description' content="用户态与内核态\rJDK早期，synchronized 叫做重量级锁， 因为申请锁资源必须通过kernel, 系统调用 ;hello.asm\r;write(int fd, const void *buffer, size_t nbytes)\rsection data\rmsg db \"Hello\", 0xA\rlen equ $ - msg\rsection .text\rglobal _start\r_start:\rmov edx, len\rmov ecx, msg\rmov ebx, 1 ;文件描述符1 std_out\rmov eax, 4 ;write函数系统调用号 4\rint 0x80\rmov ebx, 0\rmov eax, 1 ;exit函数系统调用号\rint 0x80\rCAS\rCompare And Swap (Compare And Exchange) / 自旋 / 自旋锁 / 无锁 （无重量锁）">
<meta property='og:url' content='http://laoxia.cc/p/%E5%A4%9A%E7%BA%BF%E7%A8%8B%E9%AB%98%E5%B9%B6%E5%8F%91/'>
<meta property='og:site_name' content='大国重器'>
<meta property='og:type' content='article'><meta property='article:section' content='Post' /><meta property='article:published_time' content='2018-11-11T00:00:00&#43;00:00'/><meta property='article:modified_time' content='2018-11-11T00:00:00&#43;00:00'/>
<meta name="twitter:title" content="多线程高并发">
<meta name="twitter:description" content="用户态与内核态\rJDK早期，synchronized 叫做重量级锁， 因为申请锁资源必须通过kernel, 系统调用 ;hello.asm\r;write(int fd, const void *buffer, size_t nbytes)\rsection data\rmsg db \"Hello\", 0xA\rlen equ $ - msg\rsection .text\rglobal _start\r_start:\rmov edx, len\rmov ecx, msg\rmov ebx, 1 ;文件描述符1 std_out\rmov eax, 4 ;write函数系统调用号 4\rint 0x80\rmov ebx, 0\rmov eax, 1 ;exit函数系统调用号\rint 0x80\rCAS\rCompare And Swap (Compare And Exchange) / 自旋 / 自旋锁 / 无锁 （无重量锁）">
    <link rel="shortcut icon" href="/favicon.png" />

    </head>
    <body class="
    article-page
    ">
    <script>
        (function() {
            const colorSchemeKey = 'StackColorScheme';
            if(!localStorage.getItem(colorSchemeKey)){
                localStorage.setItem(colorSchemeKey, "auto");
            }
        })();
    </script><script>
    (function() {
        const colorSchemeKey = 'StackColorScheme';
        const colorSchemeItem = localStorage.getItem(colorSchemeKey);
        const supportDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches === true;

        if (colorSchemeItem == 'dark' || colorSchemeItem === 'auto' && supportDarkMode) {
            

            document.documentElement.dataset.scheme = 'dark';
        } else {
            document.documentElement.dataset.scheme = 'light';
        }
    })();
</script>
<div class="container main-container flex on-phone--column extended"><aside class="sidebar left-sidebar sticky ">
    <button class="hamburger hamburger--spin" type="button" id="toggle-menu" aria-label="Toggle Menu">
        <span class="hamburger-box">
            <span class="hamburger-inner"></span>
        </span>
    </button>

    <header>
        
            
            <figure class="site-avatar">
                <a href="/">
                
                    
                    
                    
                        
                        <img src="/img/avatar_hue06bcb413e5a9cdb6ce4bf9a5a6157c6_4250212_300x0_resize_box_3.png" width="300"
                            height="188" class="site-logo" loading="lazy" alt="Avatar">
                    
                
                </a>
                
                    <span class="emoji">🍥</span>
                
            </figure>
            
        
        
        <div class="site-meta">
            <h1 class="site-name"><a href="/">大国重器</a></h1>
            <h2 class="site-description">The pillars of a great power. Support the backbone of a great power with code.</h2>
        </div>
    </header><ol class="menu" id="main-menu">
        
        
        
        <li >
            <a href='/' >
                
                
                
                    <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-home" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <polyline points="5 12 3 12 12 3 21 12 19 12" />
  <path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7" />
  <path d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6" />
</svg>



                
                <span>Home</span>
            </a>
        </li>
        
        
        <li >
            <a href='/archives/' >
                
                
                
                    <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-archive" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <rect x="3" y="4" width="18" height="4" rx="2" />
  <path d="M5 8v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-10" />
  <line x1="10" y1="12" x2="14" y2="12" />
</svg>



                
                <span>Archives</span>
            </a>
        </li>
        
        
        <li >
            <a href='/search/' >
                
                
                
                    <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-search" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="10" cy="10" r="7" />
  <line x1="21" y1="21" x2="15" y2="15" />
</svg>



                
                <span>Search</span>
            </a>
        </li>
        
        
        <li >
            <a href='/links/' >
                
                
                
                    <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-link" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <path d="M10 14a3.5 3.5 0 0 0 5 0l4 -4a3.5 3.5 0 0 0 -5 -5l-.5 .5" />
  <path d="M14 10a3.5 3.5 0 0 0 -5 0l-4 4a3.5 3.5 0 0 0 5 5l.5 -.5" />
</svg>



                
                <span>Links</span>
            </a>
        </li>
        
        
        <li >
            <a href='/about/' >
                
                
                
                    <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-user" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="12" cy="7" r="4" />
  <path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2" />
</svg>



                
                <span>About</span>
            </a>
        </li>
        
        <li class="menu-bottom-section">
            <ol class="menu">

                
                    <li id="dark-mode-toggle">
                        <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-left" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="8" cy="12" r="2" />
  <rect x="2" y="6" width="20" height="12" rx="6" />
</svg>



                        <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-right" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="16" cy="12" r="2" />
  <rect x="2" y="6" width="20" height="12" rx="6" />
</svg>



                        <span>Dark Mode</span>
                    </li>
                
            </ol>
        </li>
    </ol>
</aside>

    

            <main class="main full-width">
    <article class="main-article">
    <header class="article-header">

    <div class="article-details">
    
    <header class="article-category">
        
            <a href="/categories/java/" >
                Java
            </a>
        
            <a href="/categories/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" >
                多线程
            </a>
        
    </header>
    

    <div class="article-title-wrapper">
        <h2 class="article-title">
            <a href="/p/%E5%A4%9A%E7%BA%BF%E7%A8%8B%E9%AB%98%E5%B9%B6%E5%8F%91/">多线程高并发</a>
        </h2>
    
        
    </div>

    
    
    
    
    <footer class="article-time">
        
            <div>
                <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-calendar-time" width="56" height="56" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <path d="M11.795 21h-6.795a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v4" />
  <circle cx="18" cy="18" r="4" />
  <path d="M15 3v4" />
  <path d="M7 3v4" />
  <path d="M3 11h16" />
  <path d="M18 16.496v1.504l1 1" />
</svg>
                <time class="article-time--published">Nov 11, 2018</time>
            </div>
        

        
            <div>
                <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-clock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="12" cy="12" r="9" />
  <polyline points="12 7 12 12 15 15" />
</svg>



                <time class="article-time--reading">
                    10 minute read
                </time>
            </div>
        
    </footer>
    

    
</div>

</header>

    <section class="article-content">
    
    
    <!-- wp:heading {"level":1} -->
<h1>用户态与内核态</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>JDK早期，synchronized 叫做重量级锁， 因为申请锁资源必须通过kernel, 系统调用</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>;hello.asm
;write(int fd, const void *buffer, size_t nbytes)

section data
    msg db "Hello", 0xA
    len equ $ - msg

section .text
global _start
_start:

    mov edx, len
    mov ecx, msg
    mov ebx, 1 ;文件描述符1 std_out
    mov eax, 4 ;write函数系统调用号 4
    int 0x80

    mov ebx, 0
    mov eax, 1 ;exit函数系统调用号
    int 0x80</code></pre>
<!-- /wp:code -->
<!-- wp:heading {"level":1} -->
<h1>CAS</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>Compare And Swap (Compare And Exchange) / 自旋 / 自旋锁 / 无锁 （无重量锁）</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>因为经常配合循环操作，直到完成为止，所以泛指一类操作</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>cas(v, a, b) ，变量v，期待值a, 修改值b</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ABA问题，你的女朋友在离开你的这段儿时间经历了别的人，自旋就是你空转等待，一直等到她接纳你为止</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>解决办法（版本号 AtomicStampedReference），基础类型简单值不需要版本号</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>Unsafe</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>AtomicInteger:</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }

public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>Unsafe:</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>运用：</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>package com.mashibing.jol;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

public class T02_TestUnsafe {

    int i = 0;
    private static T02_TestUnsafe t = new T02_TestUnsafe();

    public static void main(String&#91;] args) throws Exception {
        //Unsafe unsafe = Unsafe.getUnsafe();

        Field unsafeField = Unsafe.class.getDeclaredFields()&#91;0];
        unsafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe) unsafeField.get(null);

        Field f = T02_TestUnsafe.class.getDeclaredField("i");
        long offset = unsafe.objectFieldOffset(f);
        System.out.println(offset);

        boolean success = unsafe.compareAndSwapInt(t, offset, 0, 1);
        System.out.println(success);
        System.out.println(t.i);
        //unsafe.compareAndSwapInt()
    }
}</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>jdk8u: unsafe.cpp:</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>cmpxchg = compare and exchange</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
  UnsafeWrapper("Unsafe_CompareAndSwapInt");
  oop p = JNIHandles::resolve(obj);
  jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
  return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>jdk8u: atomic_linux_x86.inline.hpp <strong>93行</strong></p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>is_MP = Multi Processor</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>inline jint     Atomic::cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value) {
  int mp = os::is_MP();
  __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
                    : "=a" (exchange_value)
                    : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
                    : "cc", "memory");
  return exchange_value;
}</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>jdk8u: os.hpp is_MP()</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>  static inline bool is_MP() {
    // During bootstrap if _processor_count is not yet initialized
    // we claim to be MP as that is safest. If any platform has a
    // stub generator that might be triggered in this phase and for
    // which being declared MP when in fact not, is a problem - then
    // the bootstrap routine for the stub generator needs to check
    // the processor count directly and leave the bootstrap routine
    // in place until called after initialization has ocurred.
    return (_processor_count != 1) || AssumeMP;
  }</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>jdk8u: atomic_linux_x86.inline.hpp</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>最终实现：</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>cmpxchg = cas修改变量值</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>lock cmpxchg 指令</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>硬件：</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>lock指令在执行后面指令的时候锁定一个北桥信号</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>（不采用锁总线的方式）</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>markword</h1>
<!-- /wp:heading -->
<!-- wp:heading {"level":1} -->
<h1>工具：JOL = Java Object Layout</h1>
<!-- /wp:heading -->
<!-- wp:code -->
<pre class="wp-block-code"><code>&lt;dependencies&gt;
        &lt;!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.openjdk.jol&lt;/groupId&gt;
            &lt;artifactId&gt;jol-core&lt;/artifactId&gt;
            &lt;version&gt;0.9&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>jdk8u: markOop.hpp</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>// Bit-format of an object header (most significant first, big endian layout below):
//
//  32 bits:
//  --------
//             hash:25 ------------&gt;| age:4    biased_lock:1 lock:2 (normal object)
//             JavaThread*:23 epoch:2 age:4    biased_lock:1 lock:2 (biased object)
//             size:32 ------------------------------------------&gt;| (CMS free block)
//             PromotedObject*:29 ----------&gt;| promo_bits:3 -----&gt;| (CMS promoted object)
//
//  64 bits:
//  --------
//  unused:25 hash:31 --&gt;| unused:1   age:4    biased_lock:1 lock:2 (normal object)
//  JavaThread*:54 epoch:2 unused:1   age:4    biased_lock:1 lock:2 (biased object)
//  PromotedObject*:61 ---------------------&gt;| promo_bits:3 -----&gt;| (CMS promoted object)
//  size:64 -----------------------------------------------------&gt;| (CMS free block)
//
//  unused:25 hash:31 --&gt;| cms_free:1 age:4    biased_lock:1 lock:2 (COOPs &amp;&amp; normal object)
//  JavaThread*:54 epoch:2 cms_free:1 age:4    biased_lock:1 lock:2 (COOPs &amp;&amp; biased object)
//  narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 -----&gt;| (COOPs &amp;&amp; CMS promoted object)
//  unused:21 size:35 --&gt;| cms_free:1 unused:7 ------------------&gt;| (COOPs &amp;&amp; CMS free block)</code></pre>
<!-- /wp:code -->
<!-- wp:heading {"level":1} -->
<h1>synchronized的横切面详解</h1>
<!-- /wp:heading -->
<!-- wp:list {"ordered":true} -->
<ol><li>synchronized原理</li><li>升级过程</li><li>汇编实现</li><li>vs reentrantLock的区别</li></ol>
<!-- /wp:list -->
<!-- wp:heading -->
<h2>java源码层级</h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>synchronized(o)</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2>字节码层级</h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>monitorenter moniterexit</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2>JVM层级（Hotspot）</h2>
<!-- /wp:heading -->
<!-- wp:code -->
<pre class="wp-block-code"><code>package com.mashibing.insidesync;

import org.openjdk.jol.info.ClassLayout;

public class T01_Sync1 {


    public static void main(String&#91;] args) {
        Object o = new Object();

        System.out.println(ClassLayout.parseInstance(o).toPrintable());
    }
}</code></pre>
<!-- /wp:code -->
<!-- wp:code -->
<pre class="wp-block-code"><code>com.mashibing.insidesync.T01_Sync1$Lock object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4   (object header)  05 00 00 00 (00000101 00000000 00000000 00000000) (5)
      4     4   (object header)  00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4   (object header)  49 ce 00 20 (01001001 11001110 00000000 00100000) (536923721)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total</code></pre>
<!-- /wp:code -->
<!-- wp:code -->
<pre class="wp-block-code"><code>com.mashibing.insidesync.T02_Sync2$Lock object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4   (object header)  05 90 2e 1e (00000101 10010000 00101110 00011110) (506368005)
      4     4   (object header)  1b 02 00 00 (00011011 00000010 00000000 00000000) (539)
      8     4   (object header)  49 ce 00 20 (01001001 11001110 00000000 00100000) (536923721)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes tota</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>InterpreterRuntime:: monitorenter方法</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem))
#ifdef ASSERT
  thread-&gt;last_frame().interpreter_frame_verify_monitor(elem);
#endif
  if (PrintBiasedLockingStatistics) {
    Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
  }
  Handle h_obj(thread, elem-&gt;obj());
  assert(Universe::heap()-&gt;is_in_reserved_or_null(h_obj()),
         "must be NULL or an object");
  if (UseBiasedLocking) {
    // Retry fast entry if bias is revoked to avoid unnecessary inflation
    ObjectSynchronizer::fast_enter(h_obj, elem-&gt;lock(), true, CHECK);
  } else {
    ObjectSynchronizer::slow_enter(h_obj, elem-&gt;lock(), CHECK);
  }
  assert(Universe::heap()-&gt;is_in_reserved_or_null(elem-&gt;obj()),
         "must be NULL or an object");
#ifdef ASSERT
  thread-&gt;last_frame().interpreter_frame_verify_monitor(elem);
#endif
IRT_END</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>synchronizer.cpp</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>revoke_and_rebias</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>void ObjectSynchronizer::fast_enter(Handle obj, BasicLock* lock, bool attempt_rebias, TRAPS) {
 if (UseBiasedLocking) {
    if (!SafepointSynchronize::is_at_safepoint()) {
      BiasedLocking::Condition cond = BiasedLocking::revoke_and_rebias(obj, attempt_rebias, THREAD);
      if (cond == BiasedLocking::BIAS_REVOKED_AND_REBIASED) {
        return;
      }
    } else {
      assert(!attempt_rebias, "can not rebias toward VM thread");
      BiasedLocking::revoke_at_safepoint(obj);
    }
    assert(!obj-&gt;mark()-&gt;has_bias_pattern(), "biases should be revoked by now");
 }

 slow_enter (obj, lock, THREAD) ;
}</code></pre>
<!-- /wp:code -->
<!-- wp:code -->
<pre class="wp-block-code"><code>void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) {
  markOop mark = obj-&gt;mark();
  assert(!mark-&gt;has_bias_pattern(), "should not see bias pattern here");

  if (mark-&gt;is_neutral()) {
    // Anticipate successful CAS -- the ST of the displaced mark must
    // be visible &lt;= the ST performed by the CAS.
    lock-&gt;set_displaced_header(mark);
    if (mark == (markOop) Atomic::cmpxchg_ptr(lock, obj()-&gt;mark_addr(), mark)) {
      TEVENT (slow_enter: release stacklock) ;
      return ;
    }
    // Fall through to inflate() ...
  } else
  if (mark-&gt;has_locker() &amp;&amp; THREAD-&gt;is_lock_owned((address)mark-&gt;locker())) {
    assert(lock != mark-&gt;locker(), "must not re-lock the same lock");
    assert(lock != (BasicLock*)obj-&gt;mark(), "don't relock with same BasicLock");
    lock-&gt;set_displaced_header(NULL);
    return;
  }

#if 0
  // The following optimization isn't particularly useful.
  if (mark-&gt;has_monitor() &amp;&amp; mark-&gt;monitor()-&gt;is_entered(THREAD)) {
    lock-&gt;set_displaced_header (NULL) ;
    return ;
  }
#endif

  // The object header will never be displaced to this lock,
  // so it does not matter what the value is, except that it
  // must be non-zero to avoid looking like a re-entrant lock,
  // and must not look locked either.
  lock-&gt;set_displaced_header(markOopDesc::unused_mark());
  ObjectSynchronizer::inflate(THREAD, obj())-&gt;enter(THREAD);
}</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>inflate方法：膨胀为重量级锁</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>锁升级过程</h1>
<!-- /wp:heading -->
<!-- wp:heading -->
<h2>JDK8 markword实现表：</h2>
<!-- /wp:heading -->
<!-- wp:image -->
<figure class="wp-block-image"><img src="./markword.png" alt="markword"/></figure>
<!-- /wp:image -->
<!-- wp:paragraph -->
<p>new - 偏向锁 - 轻量级锁 （无锁, 自旋锁，自适应自旋）- 重量级锁</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>synchronized优化的过程和markword息息相关</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>用markword中最低的三位代表锁状态 其中1位是偏向锁位 两位是普通锁位</p>
<!-- /wp:paragraph -->
<!-- wp:list {"ordered":true} -->
<ol><li>Object o = new Object()<br>锁 = 0 01 无锁态<br>注意：如果偏向锁打开，默认是匿名偏向状态</li><li>o.hashCode()<br>001 + hashcode</li></ol>
<!-- /wp:list -->
<!-- wp:code -->
<pre class="wp-block-code"><code>   00000001 10101101 00110100 00110110
   01011001 00000000 00000000 00000000</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>little endian big endian</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>00000000 00000000 00000000 01011001 00110110 00110100 10101101 00000000</p>
<!-- /wp:paragraph -->
<!-- wp:list {"ordered":true,"start":3} -->
<ol start="3"><li>默认synchronized(o)<br>00 -&gt; 轻量级锁<br>默认情况 偏向锁有个时延，默认是4秒<br>why? 因为JVM虚拟机自己有一些默认启动的线程，里面有好多sync代码，这些sync代码启动时就知道肯定会有竞争，如果使用偏向锁，就会造成偏向锁不断的进行锁撤销和锁升级的操作，效率较低。</li></ol>
<!-- /wp:list -->
<!-- wp:code -->
<pre class="wp-block-code"><code>   -XX:BiasedLockingStartupDelay=0</code></pre>
<!-- /wp:code -->
<!-- wp:list {"ordered":true,"start":4} -->
<ol start="4"><li>如果设定上述参数<br>new Object () - &gt; 101 偏向锁 -&gt;线程ID为0 -&gt; Anonymous BiasedLock<br>打开偏向锁，new出来的对象，默认就是一个可偏向匿名对象101</li><li>如果有线程上锁<br>上偏向锁，指的就是，把markword的线程ID改为自己线程ID的过程<br>偏向锁不可重偏向 批量偏向 批量撤销</li><li>如果有线程竞争<br>撤销偏向锁，升级轻量级锁<br>线程在自己的线程栈生成LockRecord ，用CAS操作将markword设置为指向自己这个线程的LR的指针，设置成功者得到锁</li><li>如果竞争加剧<br>竞争加剧：有线程超过10次自旋， -XX:PreBlockSpin， 或者自旋线程数超过CPU核数的一半， 1.6之后，加入自适应自旋 Adapative Self Spinning ， JVM自己控制<br>升级重量级锁：-&gt; 向操作系统申请资源，linux mutex , CPU从3级-0级系统调用，线程挂起，进入等待队列，等待操作系统的调度，然后再映射回用户空间</li></ol>
<!-- /wp:list -->
<!-- wp:paragraph -->
<p>(以上实验环境是JDK11，打开就是偏向锁，而JDK8默认对象头是无锁)</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>偏向锁默认是打开的，但是有一个时延，如果要观察到偏向锁，应该设定参数</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p><strong>如果计算过对象的hashCode，则对象无法进入偏向状态！</strong></p>
<!-- /wp:paragraph -->
<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>轻量级锁重量级锁的hashCode存在与什么地方？</p><p>答案：线程栈中，轻量级锁的LR中，或是代表重量级锁的ObjectMonitor的成员中</p></blockquote>
<!-- /wp:quote -->
<!-- wp:paragraph -->
<p>关于epoch: (不重要)</p>
<!-- /wp:paragraph -->
<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><strong>批量重偏向与批量撤销</strong>渊源：从偏向锁的加锁解锁过程中可看出，当只有一个线程反复进入同步块时，偏向锁带来的性能开销基本可以忽略，但是当有其他线程尝试获得锁时，就需要等到safe point时，再将偏向锁撤销为无锁状态或升级为轻量级，会消耗一定的性能，所以在多线程竞争频繁的情况下，偏向锁不仅不能提高性能，还会导致性能下降。于是，就有了批量重偏向与批量撤销的机制。</p><p><strong>原理</strong>以class为单位，为每个class维护<strong>解决场景</strong>批量重偏向（bulk rebias）机制是为了解决：一个线程创建了大量对象并执行了初始的同步操作，后来另一个线程也来将这些对象作为锁对象进行操作，这样会导致大量的偏向锁撤销操作。批量撤销（bulk revoke）机制是为了解决：在明显多线程竞争剧烈的场景下使用偏向锁是不合适的。</p><p>一个偏向锁撤销计数器，每一次该class的对象发生偏向撤销操作时，该计数器+1，当这个值达到重偏向阈值（默认20）时，JVM就认为该class的偏向锁有问题，因此会进行批量重偏向。每个class对象会有一个对应的epoch字段，每个处于偏向锁状态对象的Mark Word中也有该字段，其初始值为创建该对象时class中的epoch的值。每次发生批量重偏向时，就将该值+1，同时遍历JVM中所有线程的栈，找到该class所有正处于加锁状态的偏向锁，将其epoch字段改为新值。下次获得锁时，发现当前对象的epoch值和class的epoch不相等，那就算当前已经偏向了其他线程，也不会执行撤销操作，而是直接通过CAS操作将其Mark Word的Thread Id 改成当前线程Id。当达到重偏向阈值后，假设该class计数器继续增长，当其达到批量撤销的阈值后（默认40），JVM就认为该class的使用场景存在多线程竞争，会标记该class为不可偏向，之后，对于该class的锁，直接走轻量级锁的逻辑。</p></blockquote>
<!-- /wp:quote -->
<!-- wp:paragraph -->
<p>没错，我就是厕所所长</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>加锁，指的是锁定对象</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>锁升级的过程</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>JDK较早的版本 OS的资源 互斥量 用户态 -&gt; 内核态的转换 重量级 效率比较低</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>现代版本进行了优化</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>无锁 - 偏向锁 -轻量级锁（自旋锁）-重量级锁</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>偏向锁 - markword 上记录当前线程指针，下次同一个线程加锁的时候，不需要争用，只需要判断线程指针是否同一个，所以，偏向锁，偏向加锁的第一个线程 。hashCode备份在线程栈上 线程销毁，锁降级为无锁</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>有争用 - 锁升级为轻量级锁 - 每个线程有自己的LockRecord在自己的线程栈上，用CAS去争用markword的LR的指针，指针指向哪个线程的LR，哪个线程就拥有锁</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>自旋超过10次，升级为重量级锁 - 如果太多线程自旋 CPU消耗过大，不如升级为重量级锁，进入等待队列（不消耗CPU）-XX:PreBlockSpin</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>自旋锁在 JDK1.4.2 中引入，使用 -XX:+UseSpinning 来开启。JDK 6 中变为默认开启，并且引入了自适应的自旋锁（适应性自旋锁）。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>自适应自旋锁意味着自旋的时间（次数）不再固定，而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。如果在同一个锁对象上，自旋等待刚刚成功获得过锁，并且持有锁的线程正在运行中，那么虚拟机就会认为这次自旋也是很有可能再次成功，进而它将允许自旋等待持续相对更长的时间。如果对于某个锁，自旋很少成功获得过，那在以后尝试获取这个锁时将可能省略掉自旋过程，直接阻塞线程，避免浪费处理器资源。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>偏向锁由于有锁撤销的过程revoke，会消耗系统资源，所以，在锁争用特别激烈的时候，用偏向锁未必效率高。还不如直接使用轻量级锁。</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2>synchronized最底层实现</h2>
<!-- /wp:heading -->
<!-- wp:code -->
<pre class="wp-block-code"><code>public class T {
    static volatile int i = 0;

    public static void n() { i++; }

    public static synchronized void m() {}

    publics static void main(String&#91;] args) {
        for(int j=0; j&lt;1000_000; j++) {
            m();
            n();
        }
    }
}</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly T</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>C1 Compile Level 1 (一级优化)</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>C2 Compile Level 2 (二级优化)</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>找到m() n()方法的汇编码，会看到 lock comxchg …..指令</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2>synchronized vs Lock (CAS)</h2>
<!-- /wp:heading -->
<!-- wp:code -->
<pre class="wp-block-code"><code> 在高争用 高耗时的环境下synchronized效率更高
 在低争用 低耗时的环境下CAS效率更高
 synchronized到重量级之后是等待队列（不消耗CPU）
 CAS（等待期间消耗CPU）

 一切以实测为准</code></pre>
<!-- /wp:code -->
<!-- wp:heading {"level":1} -->
<h1>锁消除 lock eliminate</h1>
<!-- /wp:heading -->
<!-- wp:code -->
<pre class="wp-block-code"><code>public void add(String str1,String str2){
         StringBuffer sb = new StringBuffer();
         sb.append(str1).append(str2);
}</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>我们都知道 StringBuffer 是线程安全的，因为它的关键方法都是被 synchronized 修饰过的，但我们看上面这段代码，我们会发现，sb 这个引用只会在 add 方法中使用，不可能被其它线程引用（因为是局部变量，栈私有），因此 sb 是不可能共享的资源，JVM 会自动消除 StringBuffer 对象内部的锁。</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>锁粗化 lock coarsening</h1>
<!-- /wp:heading -->
<!-- wp:code -->
<pre class="wp-block-code"><code>public String test(String str){

       int i = 0;
       StringBuffer sb = new StringBuffer():
       while(i &lt; 100){
           sb.append(str);
           i++;
       }
       return sb.toString():
}</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>JVM 会检测到这样一连串的操作都对同一个对象加锁（while 循环内 100 次执行 append，没有锁粗化的就要进行 100 次加锁/解锁），此时 JVM 就会将加锁的范围粗化到这一连串的操作的外部（比如 while 虚幻体外），使得这一连串操作只需要加一次锁即可。</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>锁降级（不重要）</h1>
<!-- /wp:heading -->
<!-- wp:embed {"url":"https://www.zhihu.com/question/63859501"} -->
<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
https://www.zhihu.com/question/63859501
</div></figure>
<!-- /wp:embed -->
<!-- wp:paragraph -->
<p>其实，只被VMThread访问，降级也就没啥意义了。所以可以简单认为锁降级不存在！</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>超线程</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>一个ALU + 两组Registers + PC</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>参考资料</h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":1} -->
<h1>volatile的用途</h1>
<!-- /wp:heading -->
<!-- wp:heading -->
<h2>1.线程可见性</h2>
<!-- /wp:heading -->
<!-- wp:code -->
<pre class="wp-block-code"><code>package com.mashibing.testvolatile;

public class T01_ThreadVisibility {
    private static volatile boolean flag = true;

    public static void main(String&#91;] args) throws InterruptedException {
        new Thread(()-&gt; {
            while (flag) {
                //do sth
            }
            System.out.println("end");
        }, "server").start();


        Thread.sleep(1000);

        flag = false;
    }
}</code></pre>
<!-- /wp:code -->
<!-- wp:heading -->
<h2>2.防止指令重排序</h2>
<!-- /wp:heading -->
<!-- wp:heading {"level":3} -->
<h3>问题：DCL单例需不需要加volatile？</h3>
<!-- /wp:heading -->
<!-- wp:heading {"level":3} -->
<h3>CPU的基础知识</h3>
<!-- /wp:heading -->
<!-- wp:list -->
<ul><li>缓存行对齐<br>缓存行64个字节是CPU同步的基本单位，缓存行隔离会比伪共享效率要高<br>Disruptor</li></ul>
<!-- /wp:list -->
<!-- wp:code -->
<pre class="wp-block-code"><code>  package com.mashibing.juc.c_028_FalseSharing;

  public class T02_CacheLinePadding {
      private static class Padding {
          public volatile long p1, p2, p3, p4, p5, p6, p7; //
      }

      private static class T extends Padding {
          public volatile long x = 0L;
      }

      public static T&#91;] arr = new T&#91;2];

      static {
          arr&#91;0] = new T();
          arr&#91;1] = new T();
      }

      public static void main(String&#91;] args) throws Exception {
          Thread t1 = new Thread(()-&gt;{
              for (long i = 0; i &lt; 1000_0000L; i++) {
                  arr&#91;0].x = i;
              }
          });

          Thread t2 = new Thread(()-&gt;{
              for (long i = 0; i &lt; 1000_0000L; i++) {
                  arr&#91;1].x = i;
              }
          });

          final long start = System.nanoTime();
          t1.start();
          t2.start();
          t1.join();
          t2.join();
          System.out.println((System.nanoTime() - start)/100_0000);
      }
  }</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>MESI</p>
<!-- /wp:paragraph -->
<!-- wp:list -->
<ul><li>伪共享</li><li>合并写<br>CPU内部的4个字节的Buffer</li></ul>
<!-- /wp:list -->
<!-- wp:code -->
<pre class="wp-block-code"><code>  package com.mashibing.juc.c_029_WriteCombining;

  public final class WriteCombining {

      private static final int ITERATIONS = Integer.MAX_VALUE;
      private static final int ITEMS = 1 &lt;&lt; 24;
      private static final int MASK = ITEMS - 1;

      private static final byte&#91;] arrayA = new byte&#91;ITEMS];
      private static final byte&#91;] arrayB = new byte&#91;ITEMS];
      private static final byte&#91;] arrayC = new byte&#91;ITEMS];
      private static final byte&#91;] arrayD = new byte&#91;ITEMS];
      private static final byte&#91;] arrayE = new byte&#91;ITEMS];
      private static final byte&#91;] arrayF = new byte&#91;ITEMS];

      public static void main(final String&#91;] args) {

          for (int i = 1; i &lt;= 3; i++) {
              System.out.println(i + " SingleLoop duration (ns) = " + runCaseOne());
              System.out.println(i + " SplitLoop  duration (ns) = " + runCaseTwo());
          }
      }

      public static long runCaseOne() {
          long start = System.nanoTime();
          int i = ITERATIONS;

          while (--i != 0) {
              int slot = i &amp; MASK;
              byte b = (byte) i;
              arrayA&#91;slot] = b;
              arrayB&#91;slot] = b;
              arrayC&#91;slot] = b;
              arrayD&#91;slot] = b;
              arrayE&#91;slot] = b;
              arrayF&#91;slot] = b;
          }
          return System.nanoTime() - start;
      }

      public static long runCaseTwo() {
          long start = System.nanoTime();
          int i = ITERATIONS;
          while (--i != 0) {
              int slot = i &amp; MASK;
              byte b = (byte) i;
              arrayA&#91;slot] = b;
              arrayB&#91;slot] = b;
              arrayC&#91;slot] = b;
          }
          i = ITERATIONS;
          while (--i != 0) {
              int slot = i &amp; MASK;
              byte b = (byte) i;
              arrayD&#91;slot] = b;
              arrayE&#91;slot] = b;
              arrayF&#91;slot] = b;
          }
          return System.nanoTime() - start;
      }
  }</code></pre>
<!-- /wp:code -->
<!-- wp:list -->
<ul><li>指令重排序</li></ul>
<!-- /wp:list -->
<!-- wp:code -->
<pre class="wp-block-code"><code>  package com.mashibing.jvm.c3_jmm;

  public class T04_Disorder {
      private static int x = 0, y = 0;
      private static int a = 0, b =0;

      public static void main(String&#91;] args) throws InterruptedException {
          int i = 0;
          for(;;) {
              i++;
              x = 0; y = 0;
              a = 0; b = 0;
              Thread one = new Thread(new Runnable() {
                  public void run() {
                      //由于线程one先启动，下面这句话让它等一等线程two. 读着可根据自己电脑的实际性能适当调整等待时间.
                      //shortWait(100000);
                      a = 1;
                      x = b;
                  }
              });

              Thread other = new Thread(new Runnable() {
                  public void run() {
                      b = 1;
                      y = a;
                  }
              });
              one.start();other.start();
              one.join();other.join();
              String result = "第" + i + "次 (" + x + "," + y + "）";
              if(x == 0 &amp;&amp; y == 0) {
                  System.err.println(result);
                  break;
              } else {
                  //System.out.println(result);
              }
          }
      }


      public static void shortWait(long interval){
          long start = System.nanoTime();
          long end;
          do{
              end = System.nanoTime();
          }while(start + interval &gt;= end);
      }
  }</code></pre>
<!-- /wp:code -->
<!-- wp:heading {"level":3} -->
<h3>系统底层如何实现数据一致性</h3>
<!-- /wp:heading -->
<!-- wp:list {"ordered":true} -->
<ol><li>MESI如果能解决，就使用MESI</li><li>如果不能，就锁总线</li></ol>
<!-- /wp:list -->
<!-- wp:heading {"level":3} -->
<h3>系统底层如何保证有序性</h3>
<!-- /wp:heading -->
<!-- wp:list {"ordered":true} -->
<ol><li>内存屏障sfence mfence lfence等系统原语</li><li>锁总线</li></ol>
<!-- /wp:list -->
<!-- wp:heading {"level":3} -->
<h3>volatile如何解决指令重排序</h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>1: volatile i</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>2: ACC_VOLATILE</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>3: JVM的内存屏障</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>​ 屏障两边的指令不可以重排！保障有序！</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>4：hotspot实现</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>bytecodeinterpreter.cpp</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>int field_offset = cache-&gt;f2_as_index();
          if (cache-&gt;is_volatile()) {
            if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
              OrderAccess::fence();
            }</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p>orderaccess_linux_x86.inline.hpp</p>
<!-- /wp:paragraph -->
<!-- wp:code -->
<pre class="wp-block-code"><code>inline void OrderAccess::fence() {
  if (os::is_MP()) {
    // always use locked addl since mfence is sometimes expensive
#ifdef AMD64
    __asm__ volatile ("lock; addl $0,0(%%rsp)" : : : "cc", "memory");
#else
    __asm__ volatile ("lock; addl $0,0(%%esp)" : : : "cc", "memory");
#endif
  }
}</code></pre>
<!-- /wp:code -->
<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->
</section>


    <footer class="article-footer">
    

    
    <section class="article-copyright">
        <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-copyright" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z"/>
  <circle cx="12" cy="12" r="9" />
  <path d="M14.5 9a3.5 4 0 1 0 0 6" />
</svg>



        <span>Personal learning records. Please do not reprint.</span>
    </section>
    </footer>


    
</article>

    

    

<aside class="related-content--wrapper">
    <h2 class="section-title">Related content</h2>
    <div class="related-content">
        <div class="flex article-list--tile">
            
                
<article class="">
    <a href="/p/java%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B-from%E6%9C%89%E9%81%93%E4%BA%91%E7%AC%94%E8%AE%B0/">
        
        

        <div class="article-details">
            <h2 class="article-title">JAVA并发编程-from有道云笔记</h2>
        </div>
    </a>
</article>

            
                
<article class="">
    <a href="/p/jdk8-optional/">
        
        

        <div class="article-details">
            <h2 class="article-title">JDK8 Optional</h2>
        </div>
    </a>
</article>

            
                
<article class="">
    <a href="/p/%E5%8F%8D%E5%B0%84/">
        
        

        <div class="article-details">
            <h2 class="article-title">反射</h2>
        </div>
    </a>
</article>

            
        </div>
    </div>
</aside>

     
    

    <footer class="site-footer">
    <section class="copyright">
        &copy; 
        
            2017 - 
        
        2024 大国重器
    </section>
    
    <section class="powerby">
        
            Personal learning records. <br/>
        Built with <a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a> <br />
        Theme <b><a href="https://github.com/CaiJimmy/hugo-theme-stack" target="_blank" rel="noopener" data-version="3.25.0">Stack</a></b> designed by <a href="https://jimmycai.com" target="_blank" rel="noopener">Jimmy</a>
    </section>
</footer>


    
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    
    <div class="pswp__bg"></div>

    
    <div class="pswp__scroll-wrap">

        
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                
                
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div><script 
                src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"integrity="sha256-ePwmChbbvXbsO02lbM3HoHbSHTHFAeChekF1xKJdleo="crossorigin="anonymous"
                defer
                >
            </script><script 
                src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"integrity="sha256-UKkzOn/w1mBxRmLLGrSeyB4e1xbrp4xylgAWb3M42pU="crossorigin="anonymous"
                defer
                >
            </script><link 
                rel="stylesheet" 
                href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css"crossorigin="anonymous"
            ><link 
                rel="stylesheet" 
                href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css"crossorigin="anonymous"
            >

            </main>
        </div>
        <script 
                src="https://cdn.jsdelivr.net/npm/node-vibrant@3.1.6/dist/vibrant.min.js"integrity="sha256-awcR2jno4kI5X0zL8ex0vi2z&#43;KMkF24hUW8WePSA9HM="crossorigin="anonymous"
                
                >
            </script><script type="text/javascript" src="/ts/main.js" defer></script>
<script>
    (function () {
        const customFont = document.createElement('link');
        customFont.href = "https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap";

        customFont.type = "text/css";
        customFont.rel = "stylesheet";

        document.head.appendChild(customFont);
    }());
</script>

    </body>
</html>
